#include "UdxDatasetSchema.h"
#include "UdxSchemaDescription.h"

#include <emscripten/bind.h>
using namespace emscripten;
using namespace NGIS::Data::Schema;

#include <wchar.h>
#include <locale.h>

std::string ws2s(const std::wstring& ws)  
{  
	std::string curLocale = setlocale(LC_ALL, NULL); // curLocale = "C";  

	setlocale(LC_ALL, "chs");  

	const wchar_t* _Source = ws.c_str();  
	size_t _Dsize = 2 * ws.size() + 1;  
	char *_Dest = new char[_Dsize];  
	memset(_Dest,0,_Dsize);  
	wcstombs(_Dest,_Source,_Dsize);  
	std::string result = _Dest;  
	delete []_Dest;  

	setlocale(LC_ALL, curLocale.c_str());  

	return result;  
}  

std::wstring s2ws(const std::string& s)  
{  
	setlocale(LC_ALL, "chs");  

	const char* _Source = s.c_str();  
	size_t _Dsize = s.size() + 1;  
	wchar_t *_Dest = new wchar_t[_Dsize];  
	wmemset(_Dest, 0, _Dsize);  
	mbstowcs(_Dest,_Source,_Dsize);  
	std::wstring result = _Dest;  
	delete []_Dest;  

	setlocale(LC_ALL, "C");  

	return result;  
} 




float getVersion()
{
	return 1.1;
};

std::wstring getInfo()
{
	return L"我是谁？hahha";
}

int createUdxDatasetSchema()
{
	IUdxDatasetSchema* pUdxDatasetSchema = new CUdxDatasetSchema("UdxDeclaration");
	return (int)pUdxDatasetSchema;
}
	
int createUdxNodeDescription(ESchemaNodeType pNodeType, std::string pNodeInfo)
{
	CUdxSchemaDescription* pNodeDescription = new CUdxSchemaDescription(pNodeType, pNodeInfo.c_str());
	return (int)pNodeDescription;
}

int getRootNode(int pDatasetId)
{
	IUdxDatasetSchema* pDatasetNode = (IUdxDatasetSchema*)pDatasetId;
	IUdxNodeSchema* pNode = dynamic_cast<IUdxNodeSchema*>(pDatasetNode);
	return (int)pNode;
}

int addChildNode(int pParentNodeId, std::string pNodeName, ESchemaNodeType pNodeType, std::wstring pNodeInfo)
{
	IUdxNodeSchema* pParentNode = (IUdxNodeSchema*)pParentNodeId;
	std::string pNodeInfoStr = ws2s(pNodeInfo);
	IUdxNodeSchema* pNode = pParentNode->addChildNode(pNodeName.c_str(), pNodeType, pNodeInfoStr.c_str());
	return (int)pNode;
}

int removeChildNode(int pNodeId)
{
	IUdxNodeSchema* pNode = (IUdxNodeSchema*)pNodeId;
	IUdxNodeSchema* pParentNode = pNode->getParentNode();
	if (pParentNode!=NULL)
	{
		pParentNode->removeChildNode(pNode);
		return 0;
	}
	return -1;
}

int getNodeChildCount(int pNodeId)
{
	CUdxNodeSchema* pParentNode = (CUdxNodeSchema*)pNodeId;
	int childNodeCount = pParentNode->getChildNodeCount();
	return childNodeCount;
}

int getChildNode(int pParentNodeId, int idx)
{
	CUdxNodeSchema* pParentNode = (CUdxNodeSchema*)pParentNodeId;
	IUdxNodeSchema* pNode = pParentNode->getChildNode(idx);
	return (int)pNode;
}

int getParentNode(int pChildNode)
{
	CUdxNodeSchema* pNode = (CUdxNodeSchema*)pChildNode;
	IUdxNodeSchema* pParentNode = pNode->getParentNode();
	if (pParentNode!=NULL)
	{
		return (int)pParentNode;
	}
	else
		return 0;
}

std::string getNodeName(int pNodeId)
{
	CUdxNodeSchema* pNode = (CUdxNodeSchema*)pNodeId;
	std::string name = pNode->getName();
	return name;
}

std::string NodeType2String(ESchemaNodeType pNodeType)
{
	std::string typeStr = SchemaNodeType2String(pNodeType);
	return typeStr;
}

ESchemaNodeType getNodeType(int pNodeId)
{
	CUdxNodeSchema* pNode = (CUdxNodeSchema*)pNodeId;
	ESchemaNodeType nodeType = pNode->getDescription()->getKernelType();
	return nodeType;
}

std::wstring getNodeDescription(int pNodeId)
{
	CUdxNodeSchema* pNode = (CUdxNodeSchema*)pNodeId;
	std::string nodeDescription = pNode->getDescription()->getNodeDescription();
	std::wstring nodeDescriptionStr = s2ws(nodeDescription);
	return nodeDescriptionStr;
}

std::string getNodeConceptInfo(int pNodeId)
{
	IUdxNodeSchema* pNode = (IUdxNodeSchema*)pNodeId;
	std::string tag = pNode->getDescription()->getConceptTag();
	return tag;
}

std::string getNodeSpatialRefInfo(int pNodeId)
{
	IUdxNodeSchema* pNode = (IUdxNodeSchema*)pNodeId;
	std::string tag = pNode->getDescription()->getSpatialReferencefTag();
	return tag;
}

std::string getNodeUnitInfo(int pNodeId)
{
	IUdxNodeSchema* pNode = (IUdxNodeSchema*)pNodeId;
	std::string tag = pNode->getDescription()->getUnitTag();
	return tag;
}

std::string getNodeDataTemplateInfo(int pNodeId)
{
	IUdxNodeSchema* pNode = (IUdxNodeSchema*)pNodeId;
	std::string tag = pNode->getDescription()->getDataTemplateTag();
	return tag;
}

bool modifyNodeName(int pNodeId, std::wstring nodeName)
{
	IUdxNodeSchema* pNode = (IUdxNodeSchema*)pNodeId;
	if (pNode)
	{
		std::string nodeNameStr = ws2s(nodeName);
		pNode->modifyName(nodeNameStr.c_str());
	}
	return false;
}

bool modifyNodeDescription(int pNodeId, std::wstring descriptionInfo)
{
	IUdxNodeSchema* pNode = (IUdxNodeSchema*)pNodeId;
	if (pNode)
	{
		std::string description = ws2s(descriptionInfo);
		return pNode->getDescription()->modifyNodeDescription(description.c_str());
	}
	return false;
}

bool modifyNodeConceptInfo(int pNodeId, std::string tag)
{
	IUdxNodeSchema* pNode = (IUdxNodeSchema*)pNodeId;
	if (pNode)
	{
		return pNode->getDescription()->modifyConceptTag(tag.c_str());
	}
	return false;
}

bool modifyNodeSpatialRefInfo(int pNodeId, std::string tag)
{
	IUdxNodeSchema* pNode = (IUdxNodeSchema*)pNodeId;
	if (pNode)
	{
		return pNode->getDescription()->modifySpatialReferenceTag(tag.c_str());
	}
	return false;
}

bool modifyNodeUnitInfo(int pNodeId, std::string tag)
{
	IUdxNodeSchema* pNode = (IUdxNodeSchema*)pNodeId;
	if (pNode)
	{
		return pNode->getDescription()->modifyUnitTag(tag.c_str());
	}
	return false;
}

bool modifyNodeDataTemplateInfo(int pNodeId, std::string tag)
{
	IUdxNodeSchema* pNode = (IUdxNodeSchema*)pNodeId;
	if (pNode)
	{
		return pNode->getDescription()->modifyDataTemplateTag(tag.c_str());
	}
	return false;
}



std::string loadFromXmlStream(int datasetId, std::wstring xml_wstr)
{
	IUdxDatasetSchema* pDatasetNode = (IUdxDatasetSchema*)datasetId;
	if (pDatasetNode)
	{
		std::string xml_str = ws2s(xml_wstr);
		if (pDatasetNode->LoadFromXmlStream(xml_str.c_str()))
		{
			return "Parse OK";
		}
		else 
		{
			return "Parse Error";
		}
	}
	else
	{
		return "DatasetNode is NULL";
	}
}

std::wstring formatToXmlStream(int datasetId)
{
	IUdxDatasetSchema* pDatasetNode = (IUdxDatasetSchema*)datasetId;
	if (pDatasetNode)
	{
		std::string xml_str="";
		if (pDatasetNode->FormatToXmlStream(xml_str))
		{
			return s2ws(xml_str);
		}
		else
		{
			return L"Format Error";
		}
	}
	else
	{
		return L"DatasetNode is NULL";
	}
}

////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
//
//
//
//////////////////////////////////////////////////////////////////////////
float getVersion()
{
	return 1.0;
};

int createDataset()
{
	IUdxDataset* pDataset = new CUdxDataset("dataset");
	return (int)pDataset;
};

int getDatasetNode(int dxID)
{
	IUdxDataset* parentNode = (IUdxDataset*)dxID;
	IUdxNode* pNode = static_cast<IUdxNode*>(parentNode);
	return (int)pNode;
};

//////////////////////////////////////////////////////////////////////////
int getNodeChildCount(int nxID)
{
	IUdxNode* pNode = (IUdxNode*)nxID;
	return pNode->getChildNodeCount();
};

int getChildNode(int nxID, int idx)
{
	IUdxNode* pNode = (IUdxNode*)nxID;
	int count = pNode->getChildNodeCount();
	if (idx < 0 || idx >= count)
		return 0;
	return (int)(pNode->getChildNode(idx));
}

std::string getNodeName(int nxID)
{
	IUdxNode* pNode = (IUdxNode*)nxID;
	return pNode->getName();
}

bool setNodeName(int nxID, std::string pName)
{
	IUdxNode* pNode = (IUdxNode*)nxID;
	pNode->setName(pName.c_str());
}

EKernelType getNodeType(int nxID)
{
	IUdxNode* pNode = (IUdxNode*)nxID;
	return pNode->getKernel()->getType();
}

int getNodeLength(int nxID)
{
	return 0;
}


std::string kerneltype2string(EKernelType pType)
{
	return KernelType2String(pType);
}

EKernelType string2kerneltype(std::string pStr)
{
	return String2KernelType(pStr);
}

//////////////////////////////////////////////////////////////////////////
//
//
//
//////////////////////////////////////////////////////////////////////////

int addChildNode(int nxID, std::string name, EKernelType type)
{
	IUdxNode* parentNode = (IUdxNode*)nxID;
	IUdxNode* pNode = parentNode->addChildNode(name.c_str(), type);
	return (int)pNode;
};

bool setIntNodeValue(int nxID, int value)
{
	IUdxNode* pNode = (IUdxNode*)nxID;
	if (pNode->getKernel()->getType() != EKernelType::EKT_INT)
		return false;
	IUdxKernelIntValue* realKernel = (IUdxKernelIntValue*)pNode->getKernel();
	realKernel->setTypedValue(value);
	return true;
};

bool setRealNodeValue(int nxID, double value)
{
	IUdxNode* pNode = (IUdxNode*)nxID;
	if (pNode->getKernel()->getType() != EKernelType::EKT_REAL)
		return false;
	IUdxKernelRealValue* realKernel = (IUdxKernelRealValue*)pNode->getKernel();
	realKernel->setTypedValue(value);
	return true;
};

bool setStringNodeValue(int nxID, std::string value)
{
	IUdxNode* pNode = (IUdxNode*)nxID;
	if (pNode->getKernel()->getType() != EKernelType::EKT_STRING)
		return false;
	IUdxKernelStringValue* realKernel = (IUdxKernelStringValue*)pNode->getKernel();
	realKernel->setTypedValue(value);
	return true;
};

bool setVector2dNodeValue(int nxID, double x, double y)
{
	IUdxNode* pNode = (IUdxNode*)nxID;
	if (pNode->getKernel()->getType() != EKernelType::EKT_VECTOR2)
		return false;
	IUdxKernelVector2dValue* realKernel = (IUdxKernelVector2dValue*)pNode->getKernel();
	realKernel->setTypedValue(x, y);
	return true;
};

bool setVector3dNodeValue(int nxID, double x, double y, double z)
{
	IUdxNode* pNode = (IUdxNode*)nxID;
	if (pNode->getKernel()->getType() != EKernelType::EKT_VECTOR3)
		return false;
	IUdxKernelVector3dValue* realKernel = (IUdxKernelVector3dValue*)pNode->getKernel();
	realKernel->setTypedValue(x, y, z);
	return true;
};

bool setVector4dNodeValue(int nxID, double x, double y, double z, double m)
{
	IUdxNode* pNode = (IUdxNode*)nxID;
	if (pNode->getKernel()->getType() != EKernelType::EKT_VECTOR4)
		return false;
	IUdxKernelVector4dValue* realKernel = (IUdxKernelVector4dValue*)pNode->getKernel();
	realKernel->setTypedValue(x, y, z, m);
	return true;
};

//////////////////////////////////////////////////////////////////////////
bool addIntNodeValue(int nxID, int value, int idx)
{
	IUdxNode* pNode = (IUdxNode*)nxID;
	if (pNode->getKernel()->getType() != EKernelType::EKT_INT_LIST)
		return false;
	IUdxKernelIntArray* realKernel = (IUdxKernelIntArray*)pNode->getKernel();
	if (realKernel->getCount() > idx)
	{
		realKernel->setTypedValue(value, idx);
	}
	else
	{
		realKernel->addTypedValue(value);
	}
	return true;
};

bool addRealNodeValue(int nxID, double value, int idx)
{
	IUdxNode* pNode = (IUdxNode*)nxID;
	if (pNode->getKernel()->getType() != EKernelType::EKT_REAL_LIST)
		return false;
	IUdxKernelRealArray* realKernel = (IUdxKernelRealArray*)pNode->getKernel();
	if (realKernel->getCount() > idx)
	{
		realKernel->setTypedValue(value, idx);
	}
	else
	{
		realKernel->addTypedValue(value);
	}
	return true;
};

bool addStringNodeValue(int nxID, std::string value, int idx)
{
	IUdxNode* pNode = (IUdxNode*)nxID;
	if (pNode->getKernel()->getType() != EKernelType::EKT_STRING_LIST)
		return false;
	IUdxKernelStringArray* realKernel = (IUdxKernelStringArray*)pNode->getKernel();
	if (realKernel->getCount() > idx)
	{
		realKernel->setTypedValue(value, idx);
	}
	else
	{
		realKernel->addTypedValue(value);
	}
	return true;
};

bool addVector2dNodeValue(int nxID, double x, double y, int idx)
{
	IUdxNode* pNode = (IUdxNode*)nxID;
	if (pNode->getKernel()->getType() != EKernelType::EKT_VECTOR2_LIST)
		return false;
	IUdxKernelVector2dArray* realKernel = (IUdxKernelVector2dArray*)pNode->getKernel();
	if (realKernel->getCount() > idx)
	{
		realKernel->setTypedValue(Vector2d(x, y), idx);
	}
	else
	{
		realKernel->addTypedValue(x, y);
	}
	return true;
};

bool addVector3dNodeValue(int nxID, double x, double y, double z, int idx)
{
	IUdxNode* pNode = (IUdxNode*)nxID;
	if (pNode->getKernel()->getType() != EKernelType::EKT_VECTOR3_LIST)
		return false;
	IUdxKernelVector3dArray* realKernel = (IUdxKernelVector3dArray*)pNode->getKernel();
	if (realKernel->getCount() > idx)
	{
		realKernel->setTypedValue(Vector3d(x, y, z), idx);
	}
	else
	{
		realKernel->addTypedValue(x, y, z);
	}
	return true;
};

bool addVector4dNodeValue(int nxID, double x, double y, double z, double m, int idx)
{
	IUdxNode* pNode = (IUdxNode*)nxID;
	if (pNode->getKernel()->getType() != EKernelType::EKT_VECTOR4_LIST)
		return false;
	IUdxKernelVector4dArray* realKernel = (IUdxKernelVector4dArray*)pNode->getKernel();
	if (realKernel->getCount() > idx)
	{
		realKernel->setTypedValue(Vector4d(x, y, z, m), idx);
	}
	else
	{
		realKernel->addTypedValue(x, y, z, m);
	}
	return true;
};

//////////////////////////////////////////////////////////////////////////
int getNodeIntValue(int node)
{
	IUdxNode* pNode = (IUdxNode*)node;
	if (pNode->getKernel()->getType() != EKernelType::EKT_INT)
		return false;
	IUdxKernelIntValue* realKernel = (IUdxKernelIntValue*)pNode->getKernel();
	return realKernel->getTypedValue();
}

double getNodeRealValue(int node)
{
	IUdxNode* pNode = (IUdxNode*)node;
	if (pNode->getKernel()->getType() != EKernelType::EKT_REAL)
		return false;
	IUdxKernelRealValue* realKernel = (IUdxKernelRealValue*)pNode->getKernel();
	return realKernel->getTypedValue();
}

std::string getNodeStringValue(int node)
{
	IUdxNode* pNode = (IUdxNode*)node;
	if (pNode->getKernel()->getType() != EKernelType::EKT_STRING)
		return "";
	IUdxKernelStringValue* realKernel = (IUdxKernelStringValue*)pNode->getKernel();
	return realKernel->getTypedValue();
}

Vector2d getNodeVector2dValue(int node)
{
	IUdxNode* pNode = (IUdxNode*)node;
	if (pNode->getKernel()->getType() != EKernelType::EKT_VECTOR2)
		return Vector2d(0,0);
	IUdxKernelVector2dValue* realKernel = (IUdxKernelVector2dValue*)pNode->getKernel();
	return realKernel->getTypedValue();
}

Vector3d getNodeVector3dValue(int node)
{
	IUdxNode* pNode = (IUdxNode*)node;
	if (pNode->getKernel()->getType() != EKernelType::EKT_VECTOR3)
		return Vector3d(0,0,0);
	IUdxKernelVector3dValue* realKernel = (IUdxKernelVector3dValue*)pNode->getKernel();
	return realKernel->getTypedValue();
}

Vector4d getNodeVector4dValue(int node)
{
	IUdxNode* pNode = (IUdxNode*)node;
	if (pNode->getKernel()->getType() != EKernelType::EKT_VECTOR4)
		return Vector4d(0,0,0,0);
	IUdxKernelVector4dValue* realKernel = (IUdxKernelVector4dValue*)pNode->getKernel();
	return realKernel->getTypedValue();
}

//////////////////////////////////////////////////////////////////////////
int getNodeIntArrayValue(int node, int idx)
{
	IUdxNode* pNode = (IUdxNode*)node;
	if (pNode->getKernel()->getType() != EKernelType::EKT_INT_LIST)
		return false;
	IUdxKernelIntArray* realKernel = (IUdxKernelIntArray*)pNode->getKernel();
	int retVal = 0;
	realKernel->getTypedValueByIndex(idx, retVal);
	return retVal;
}

double getNodeRealArrayValue(int node, int idx)
{
	IUdxNode* pNode = (IUdxNode*)node;
	if (pNode->getKernel()->getType() != EKernelType::EKT_REAL_LIST)
		return 0.0;
	IUdxKernelRealArray* realKernel = (IUdxKernelRealArray*)pNode->getKernel();
	double retVal = 0.0;
	realKernel->getTypedValueByIndex(idx, retVal);
	return retVal;
}

std::string getNodeStringArrayValue(int node, int idx)
{
	IUdxNode* pNode = (IUdxNode*)node;
	if (pNode->getKernel()->getType() != EKernelType::EKT_STRING_LIST)
		return "";
	IUdxKernelStringArray* realKernel = (IUdxKernelStringArray*)pNode->getKernel();
	std::string retVal = "";
	realKernel->getTypedValueByIndex(idx, retVal);
	return retVal;
}

Vector2d getNodeVector2dArrayValue(int node, int idx)
{
	IUdxNode* pNode = (IUdxNode*)node;
	if (pNode->getKernel()->getType() != EKernelType::EKT_VECTOR2_LIST)
		return Vector2d(0,0);
	IUdxKernelVector2dArray* realKernel = (IUdxKernelVector2dArray*)pNode->getKernel();
	Vector2d retVal; 
	realKernel->getTypedValueByIndex(idx, retVal);
	return retVal;
}

Vector3d getNodeVector3dArrayValue(int node, int idx)
{
	IUdxNode* pNode = (IUdxNode*)node;
	if (pNode->getKernel()->getType() != EKernelType::EKT_VECTOR3_LIST)
		return Vector3d(0,0,0);
	IUdxKernelVector3dArray* realKernel = (IUdxKernelVector3dArray*)pNode->getKernel();
	Vector3d retVal; 
	realKernel->getTypedValueByIndex(idx, retVal);
	return retVal;
}

Vector4d getNodeVector4dArrayValue(int node, int idx)
{
	IUdxNode* pNode = (IUdxNode*)node;
	if (pNode->getKernel()->getType() != EKernelType::EKT_VECTOR4_LIST)
		return Vector4d(0,0,0,0);
	IUdxKernelVector4dArray* realKernel = (IUdxKernelVector4dArray*)pNode->getKernel();
	Vector4d retVal; 
	realKernel->getTypedValueByIndex(idx, retVal);
	return retVal;
}

//////////////////////////////////////////////////////////////////////////
//
//
//
//////////////////////////////////////////////////////////////////////////

std::string udx_formatToXmlStr(int dxObj)
{
	std::string xml_str = "";
	IUdxDataset* pNode = (IUdxDataset*)dxObj;
	pNode->FormatXmlStream(xml_str);

	return xml_str;
}

bool udx_loadFromXmlStr(int dxObj, std::string xml_str)
{
	IUdxDataset* pNode = (IUdxDataset*)dxObj;
	if (pNode->LoadXmlStream(xml_str.c_str()))
		return true;
	else
		return false;
}












EMSCRIPTEN_BINDINGS(udx_data_module) {
	enum_<EKernelType>("KernelType")
		.value("EKT_NULL", EKT_NULL)
		.value("EKT_INT", EKT_INT)
		.value("EKT_REAL", EKT_REAL)
		.value("EKT_STRING", EKT_STRING)
		.value("EKT_VECTOR2", EKT_VECTOR2)
		.value("EKT_VECTOR3", EKT_VECTOR3)
		.value("EKT_VECTOR4", EKT_VECTOR4)
		.value("EKT_NODE", EKT_NODE)
		.value("EKT_LIST", EKT_LIST)
		.value("EKT_MAP", EKT_MAP)
		.value("EKT_TABLE", EKT_TABLE)
		.value("EKT_INT_LIST", EKT_INT_LIST)
		.value("EKT_REAL_LIST", EKT_REAL_LIST)
		.value("EKT_STRING_LIST", EKT_STRING_LIST)
		.value("EKT_VECTOR2_LIST", EKT_VECTOR2_LIST)
		.value("EKT_VECTOR3_LIST", EKT_VECTOR3_LIST)
		.value("EKT_VECTOR4_LIST", EKT_VECTOR4_LIST)
		.value("EKT_COUNT", EKT_COUNT)
		;

	value_array<Vector2d>("Vector2d")
		.element(&Vector2d::x)
		.element(&Vector2d::y)
		;

	value_array<Vector3d>("Vector3d")
		.element(&Vector3d::x)
		.element(&Vector3d::y)
		.element(&Vector3d::z)
		;

	value_array<Vector4d>("Vector4d")
		.element(&Vector4d::x)
		.element(&Vector4d::y)
		.element(&Vector4d::z)
		.element(&Vector4d::m)
		;

	function("getVersion", &getVersion);
	function("createDataset", &createDataset);
	function("getDatasetNode", &getDatasetNode);

	function("getNodeChildCount", &getNodeChildCount);
	function("getChildNode", &getChildNode);
	function("getNodeName", &getNodeName);
	function("setNodeName", &setNodeName);
	function("getNodeType", &getNodeType);
	function("getNodeLength", &getNodeLength);
	function("kerneltype2string", &kerneltype2string);
	function("string2kerneltype", &string2kerneltype);

	function("addChildNode", &addChildNode);
	function("setIntNodeValue", &setIntNodeValue);
	function("setRealNodeValue", &setRealNodeValue);
	function("setStringNodeValue", &setStringNodeValue);
	function("setVector2dNodeValue", &setVector2dNodeValue);
	function("setVector3dNodeValue", &setVector3dNodeValue);
	function("setVector4dNodeValue", &setVector4dNodeValue);
	function("addIntNodeValue", &addIntNodeValue);
	function("addRealNodeValue", &addRealNodeValue);
	function("addStringNodeValue", &addStringNodeValue);
	function("addVector2dNodeValue", &addVector2dNodeValue);
	function("addVector3dNodeValue", &addVector3dNodeValue);
	function("addVector4dNodeValue", &addVector4dNodeValue);

	function("getNodeIntValue", &getNodeIntValue);
	function("getNodeRealValue", &getNodeRealValue);
	function("getNodeStringValue", &getNodeStringValue);
	function("getNodeVector2dValue", &getNodeVector2dValue);
	function("getNodeVector3dValue", &getNodeVector3dValue);
	function("getNodeVector4dValue", &getNodeVector4dValue);

	function("getNodeIntArrayValue", &getNodeIntArrayValue);
	function("getNodeRealArrayValue", &getNodeRealArrayValue);
	function("getNodeStringArrayValue", &getNodeStringArrayValue);
	function("getNodeVector2dArrayValue", &getNodeVector2dArrayValue);
	function("getNodeVector3dArrayValue", &getNodeVector3dArrayValue);
	function("getNodeVector4dArrayValue", &getNodeVector4dArrayValue);

	function("formatToXmlStream1", &udx_formatToXmlStr);
	function("loadFromXmlStream1", &udx_loadFromXmlStr);
}

EMSCRIPTEN_BINDINGS(udx_schema_module) {
	enum_<ESchemaNodeType>("SchemaNodeType")
		.value("EDTKT_INT", EDTKT_INT)
		.value("EDTKT_REAL", EDTKT_REAL)
		.value("EDTKT_VECTOR2", EDTKT_VECTOR2)
		.value("EDTKT_VECTOR3", EDTKT_VECTOR3)
		.value("EDTKT_VECTOR4", EDTKT_VECTOR4)
		.value("EDTKT_STRING", EDTKT_STRING)
		.value("EDTKT_INT_LIST", (ESchemaNodeType)(EDTKT_INT|EDTKT_LIST))
		.value("EDTKT_REAL_LIST", (ESchemaNodeType)(EDTKT_REAL|EDTKT_LIST))
		.value("EDTKT_VECTOR2_LIST", (ESchemaNodeType)(EDTKT_VECTOR2|EDTKT_LIST))
		.value("EDTKT_VECTOR3_LIST", (ESchemaNodeType)(EDTKT_VECTOR3|EDTKT_LIST))
		.value("EDTKT_VECTOR4_LIST", (ESchemaNodeType)(EDTKT_VECTOR4|EDTKT_LIST))
		.value("EDTKT_STRING_LIST", (ESchemaNodeType)(EDTKT_STRING|EDTKT_LIST))
		.value("EDTKT_NODE", EDTKT_NODE)
		.value("EDTKT_LIST", EDTKT_LIST)
		.value("EDTKT_MAP", EDTKT_MAP)
		.value("EDTKT_TABLE", EDTKT_TABLE)
		;
		
	function("getVersion", &getVersion);
	function("getInfo", &getInfo);
	
	function("createUdxDatasetSchema", &createUdxDatasetSchema);
	function("createUdxNodeDescription", &createUdxNodeDescription);
	function("getRootNode", &getRootNode);
	function("addChildNode", &addChildNode);
	function("removeChildNode", &removeChildNode);
	
	function("getNodeChildCount", &getNodeChildCount);
	function("getChildNode", &getChildNode);
	function("getNodeType", &getNodeType);

	function("NodeType2String", &NodeType2String);

	function("getNodeName", &getNodeName);
	function("getNodeDescription", &getNodeDescription);
	function("getNodeConceptInfo", &getNodeConceptInfo);
	function("getNodeSpatialRefInfo", &getNodeSpatialRefInfo);
	function("getNodeUnitInfo", &getNodeUnitInfo);
	function("getNodeDataTemplateInfo", &getNodeDataTemplateInfo);

	function("modifyNodeName", &modifyNodeName);
	function("modifyNodeDescription", &modifyNodeDescription);
	function("modifyNodeConceptInfo", &modifyNodeConceptInfo);
	function("modifyNodeSpatialRefInfo", &modifyNodeSpatialRefInfo);
	function("modifyNodeUnitInfo", &modifyNodeUnitInfo);
	function("modifyNodeDataTemplateInfo", &modifyNodeDataTemplateInfo);

	function("loadFromXmlStream", &loadFromXmlStream);
	function("formatToXmlStream", &formatToXmlStream);
}



